package com.ruoyi.web.schedule;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.web.domain.Currency;
import com.ruoyi.web.domain.WithdrawalRecord;
import com.ruoyi.web.dto.TronWithdrawal;
import com.ruoyi.web.enums.UserEnums;
import com.ruoyi.web.enums.WalletStatusEnums;
import com.ruoyi.web.service.IAppUserService;
import com.ruoyi.web.service.ICurrencyService;
import com.ruoyi.web.service.IWithdrawalRecordService;
import lombok.AllArgsConstructor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

/**
 * 提现区块确认
 *
 */
@Component
@EnableScheduling
@AllArgsConstructor
public class WithdrawalRecordCheckTask {

    private final IWithdrawalRecordService withdrawalRecordService;

    private final IAppUserService userService;

    private final ICurrencyService currencyService;

    private final OkHttpClient okHttpClient = new OkHttpClient();

    @Scheduled(fixedDelay = 1000)
    public void withdrawalCheckTask() {
        try {
            List<WithdrawalRecord> records = withdrawalRecordService.selectWithdrawalRecordList(new WithdrawalRecord() {{
                setState(WalletStatusEnums.Status.WITHDRAWING.getValue());
            }});
            for (WithdrawalRecord record : records) {
                Currency currency = currencyService.getCurrency(record.getPublicChain());
                if (currency == null) {
                    continue;
                }
                if (record.getPublicChain().equals(UserEnums.Chain.BSC.getValue()) ||
                        record.getPublicChain().equals(UserEnums.Chain.ETH.getValue())) {
                    Web3j web3j = Web3j.build(new HttpService(currency.getNodeAddress() + currency.getApiKey()));
                    Request<?, EthGetTransactionReceipt> ethGetTransactionReceiptRequest = web3j.ethGetTransactionReceipt(record.getTransactionHash());
                    EthGetTransactionReceipt send = ethGetTransactionReceiptRequest.send();
                    Optional<TransactionReceipt> transactionReceipt = send.getTransactionReceipt();
                    if (transactionReceipt.isPresent()) {
                        record.setState(WalletStatusEnums.Status.SUCCESS.getValue());
                    } else {
                        record.setState(WalletStatusEnums.Status.FAIL.getValue());
                    }
                }
                if (record.getPublicChain().equals(UserEnums.Chain.TRX.getValue())) {
                    MediaType mediaType = MediaType.parse("application/json");
                    RequestBody body = RequestBody.create(mediaType, "{\"value\":\"" + record.getTransactionHash() + "\"}");
                    okhttp3.Request request = new okhttp3.Request.Builder()
                            .url(currency.getNodeAddress() + "walletsolidity/gettransactionbyid")
                            .post(body)
                            .addHeader("Accept", "application/json")
                            .addHeader("Content-Type", "application/json")
                            .build();
                    Response response = null;
                    try {
                        response = okHttpClient.newCall(request).execute();
                    } catch (IOException e) {
                        continue;
                    }
                    String res = null;
                    try {
                        res = response.body().string();
                    } catch (IOException e) {
                        continue;
                    }
                    TronWithdrawal tronWithdrawal = JSONUtil.toBean(res, TronWithdrawal.class);

                    if (!CollUtil.isNotEmpty(tronWithdrawal.getRet())) {
                        continue;
                    }
                    if ("SUCCESS".equals(tronWithdrawal.getRet().get(0).getContractRet())) {
                        record.setState(WalletStatusEnums.Status.SUCCESS.getValue());
                    } else {
                        record.setState(WalletStatusEnums.Status.FAIL.getValue());
                    }
                }
                withdrawalRecordService.updateWithdrawalRecord(record);
            }
        } catch (Exception e) {

        }
    }

}
